package com.huiquan.vocab.service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.huiquan.analysis.domain.User;
import com.huiquan.framework.base.BaseService;
import com.huiquan.framework.base.ReturnData;
import com.huiquan.framework.utils.ReturnUtil;
import com.huiquan.framework.utils.StringPatternUtils;
import com.huiquan.vocab.constant.TQuanzationRule;
import com.huiquan.vocab.dao.VocabElementDao;
import com.huiquan.vocab.domain.VocabElement;

@Service
public class VocabElementTService extends BaseService {

	@Autowired
	private VocabElementDao vocabElementDao;

	public ReturnData elementChangeQuantization(String id, String quantization, User user) {

		LOGGER.info("Update quantization start!id=" + id + ";quantization=" + quantization);

		// 根据id更改量化
		vocabElementDao.updateQuantization(Long.parseLong(id), quantization, user);

		LOGGER.info("Update quantization end!");

		return ReturnUtil.success();
	}

	public void elementTimeQuantizationInit() {

		LOGGER.info("property t Quantization Init begin!");
		Map<String, Object> param = new HashMap<>();
		param.put("flag", 0);
		param.put("property", "t");
		param.put("quantizationFlag", "0");
		// 初始化量化正确的小词t
		List<VocabElement> list = vocabElementDao.retrieveList(param);
		for (VocabElement value : list) {
			String vocab = value.getVocabulary();
			String subCount = quantizationT(vocab);
			if (StringUtils.isNotBlank(subCount)) {
				value.setQuantization(subCount);
				vocabElementDao.update(value);
			}
		}
		LOGGER.info("property t Quantization Init end!");

	}

	public void elementTimeQuantizationTest() {
		Map<String, Object> param = new HashMap<>();
		param.put("flag", 0);
		param.put("property", "t");
		// 初始化量化正确的小词t
		List<VocabElement> list = vocabElementDao.retrieveList(param);
		for (VocabElement value : list) {
			String vocab = value.getVocabulary();
			String tq = value.getQuantization();
			String subCount = quantizationT(vocab);
			if (!tq.isEmpty() && !tq.equals(subCount)) {

				LOGGER.info("id=" + value.getId() + "|vocabulary=" + vocab + "|tq=" + tq + "|subCount=" + subCount);
			}
		}
	}

	public String changeTraditional(String vocab) {

		for (int i = 0; i < vocab.length(); i++) {
			char value = vocab.charAt(i);
			if (TQuanzationRule.numCHChangeMap.get(value + "") != null) {
				vocab = vocab.replace(value + "", TQuanzationRule.numCHChangeMap.get(value + ""));
			}
		}
		return vocab;
	}

	private String quantizationT(String vocab) {

		// 近多出现先把近干掉
		if (vocab.indexOf("近多") > -1) {
			vocab = vocab.replace("近", "");
		}

		// 忽略词
		String ignored = vocab.replaceAll(TQuanzationRule.ignoreRegex, "");

		// 替换
		String replaced = replaceVocab(ignored);
		for (String special : TQuanzationRule.specialMap.keySet()) {
			if (replaced.indexOf(special) > -1) {
				return TQuanzationRule.specialMap.get(special);
			}
		}
		replaced = replaced.replace("前", "");

		// 抽取单位
		List<String> unitList = StringPatternUtils.getGroups(TQuanzationRule.unitRegex, replaced);
		if (unitList.size() != 1) {
			return "";
		}
		String unit = unitList.get(0);
		String removedUnit = replaced.replaceAll(TQuanzationRule.unitRegex, "");

		// 特殊字：至，如果该字两边都是数字则将至替换为-，否则忽略该字
		if (removedUnit.indexOf("至") > -1) {
			String[] numStrs = removedUnit.split("至");
			if (numStrs.length == 2 && getInteger(numStrs[0]) != null && getInteger(numStrs[1]) != null) {
				removedUnit = removedUnit.replace("至", "-");
			} else {
				removedUnit = removedUnit.replace("至", "");
			}
		}
		// 特殊字：近，如果数字里只有近则补1，否则忽略
		if (removedUnit.indexOf("近") > -1) {
			if (removedUnit.equals("近") && "年月周".indexOf(unit) > -1) {
				removedUnit = "1";
			} else {
				removedUnit = removedUnit.replace("近", "");
			}
		}
		// 特殊字：一，如果一两边都是正实数的话，则将一替换成-
		if (removedUnit.indexOf("一") > -1) {
			String[] numStrs = removedUnit.split("一");
			if (numStrs.length == 2 && StringPatternUtils.getPositiveInteger(numStrs[0]) != null
					&& StringPatternUtils.getPositiveInteger(numStrs[1]) != null) {
				removedUnit = removedUnit.replace("一", "-");
			}
		}

		// 获取数字并根据模板获取结果
		String result = getResult(removedUnit, unit);

		return result;
	}

	private String getResult(String number, String unit) {
		// trim掉前后空格
		number = number.trim();
		unit = unit.trim();

		// 如果数字字符串为空则设置默认值
		if (number.isEmpty()) {
			return getResultByTemplate1(TQuanzationRule.DEFAULT_T_NUMBER, unit);
		}
		Pattern separatorPattern = Pattern.compile(TQuanzationRule.separatorRegex);
		Integer n = null;
		Double d = null;

		if (number.startsWith("数") || number.endsWith("数") || number.startsWith("几") || number.endsWith("几")) {
			// 带有数、几的词，如果是在两边的话
			String sjNumber = number.replaceAll("[数几]", "");
			if (sjNumber.isEmpty()) {
				return getResultByTemplate1(TQuanzationRule.DEFAULT_T_NUMBER, unit);
			} else {
				n = getInteger(sjNumber);
				if (n == null) {
					return "";
				}

				if (number.startsWith("数") || number.startsWith("几")) {
					n = n * TQuanzationRule.DEFAULT_T_NUMBER;
				} else {
					n = n + TQuanzationRule.DEFAULT_T_NUMBER;
				}

				return getResultByTemplate1(n, unit);
			}
		} else if (number.startsWith("半") || number.endsWith("半")) {
			String bNumber = number.replace("半", "");
			if (bNumber.isEmpty()) {
				return getResultByTemplate1(TQuanzationRule.DEFAULT_T_NUMBER_BAN, unit);
			} else {
				n = getInteger(bNumber);
				if (n == null) {
					return "";
				}

				return getResultByTemplate1(n + 0.5, unit);
			}
		} else if (separatorPattern.matcher(number).find()) {
			// 如果可以分割，则需要两边都是数字
			number = number.replaceAll(TQuanzationRule.separatorRegex, "-");
			String[] separatorNum = number.split("-");
			if (separatorNum.length == 2) {
				Integer n1 = getInteger(separatorNum[0]);
				Integer n2 = getInteger(separatorNum[1]);
				if (n1 == null || n2 == null) {
					return "";
				}
				return getResultByTemplate1((n1 + n2) / 2.0, unit);
			}
		} else if (number.indexOf("+") > -1) {
			String[] plusSplit = number.split("\\+");
			if (plusSplit.length == 2) {
				Integer n1 = getInteger(plusSplit[0]);
				Integer n2 = getInteger(plusSplit[1]);

				if (n1 != null && n2 != null && (unit.equals("天") || unit.equals("周"))) {
					return (n1 * 7 + n2) + "";
				}
			} else {
				String removePlusChar = number.replaceAll("^[\\+]*", "").replaceAll("[\\+]*$", "");
				n = getInteger(removePlusChar);
				if (n != null) {

					return getResultByTemplate1(n, unit);
				}
			}

		} else if ((n = getInteger(number)) != null) {

			return getResultByTemplate1(n, unit);
		} else if ((d = StringPatternUtils.getPositiveRealNumber(number)) != null) {

			return getResultByTemplate1(d, unit);
		} else if (Pattern.matches(TQuanzationRule.numCHRegex + "{2}", number)) {

			String[] separatorNum = number.split("");
			Integer n1 = getInteger(separatorNum[0]);
			Integer n2 = getInteger(separatorNum[1]);

			return getResultByTemplate1((n1 + n2) / 2.0, unit);
		} else {
			// 去掉中文数字
			String removeCHnum = number.replaceAll(TQuanzationRule.numCHRegex, "");
			Integer arabNum = StringPatternUtils.getPositiveInteger(removeCHnum);
			if (arabNum != null && arabNum < 10) {
				Integer CHNum = getInteger(number.replace(removeCHnum, ""));
				return getResultByTemplate1((arabNum + CHNum) / 2.0, unit);
			}
		}

		return "";
	}

	private Integer getInteger(String number) {

		Integer n = StringPatternUtils.getPositiveInteger(number);
		if (n == null) {
			n = StringPatternUtils.fomatMixedCHArabPositiveInteger(number);
		}

		return n;
	}

	/**
	 * 模板1：[数字][单位]
	 * 
	 * @param number
	 * @param unit
	 * @return
	 */
	private String getResultByTemplate1(double number, String unit) {

		Double multiple = TQuanzationRule.unitMutipleMap.get(unit);
		if (multiple == null) {
			return "";
		}

		BigDecimal mul = new BigDecimal(multiple);
		BigDecimal num2 = new BigDecimal(number);
		BigDecimal count = mul.multiply(num2).setScale(5, BigDecimal.ROUND_HALF_UP);

		if (new BigDecimal(count.intValue()).equals(count)) {
			return count.intValue() + "";
		} else {
			return count.stripTrailingZeros().toPlainString();
		}
	}

	private String replaceVocab(String ignoredVocab) {

		for (String key : TQuanzationRule.replaceMap.keySet()) {
			ignoredVocab = ignoredVocab.replace(key, TQuanzationRule.replaceMap.get(key));
		}
		return ignoredVocab;
	}

	public void initTSynonymy() {
		LOGGER.info(" property t init synonymy  begin !");
		vocabElementDao.initTSynonymy();
		LOGGER.info(" property t init synonymy  end !");
	}
}
